package cn.tedu.csmall.all.adapter.service;

import cn.tedu.csmall.all.adapter.mapper.OrderMapper;
import cn.tedu.csmall.all.service.IOrderService;
import cn.tedu.csmall.commons.pojo.order.dto.OrderAddDTO;
import cn.tedu.csmall.commons.pojo.order.entity.Order;
import cn.tedu.csmall.commons.restful.JsonPage;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboService;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.messaging.Message;
import org.springframework.messaging.support.MessageBuilder;
import org.springframework.stereotype.Service;
import java.util.List;


@DubboService(loadbalance = "random")//order模块作为provider角色的注解(给提供服务的service实现类标注@DubboService注解)
@Service
@Slf4j
public class OrderServiceImpl implements IOrderService {

    @Autowired
    private OrderMapper  orderMapper;

    //Order模块调用stock模块和cart模块
    /**
     * 防止消息异步消费逻辑中,重复消费的问题,业务方法
     * 设计成幂等的
     * @param orderAddDTO
     */
    @Autowired
    private RocketMQTemplate  rocketMQTemplate;

    /**
     *  下边两行代码换成上边的RocketMQ消息队列调用了
     *  @DubboReference表示order模块要调用stock模块的服务
     *  调用的是order模块以dubbo服务注册到nacos中的服务
     */
    /*@DubboReference
    private IStockService stockService;

    private ICartService cartService;*/




    public void orderAdd(OrderAddDTO orderAddDTO) {
        int count=orderMapper.selectExists(orderAddDTO);
        if(count>0){
            log.debug("订单已经新增了");
            return;
        }
        //发送一个半消息,消息如果发送成功,是给购物车用的
        //只要包含当前订单用户,的订单商品是什么 消息特点精简准确
        //消息不仅只有消费者在使用,还有本地事务,和检查事务的方法都在使用
        //主要考虑check检查,如果消息本身携带的内容不足以支持检查逻辑
        //需要想办法携带更多信息
        String msgData=orderAddDTO.getUserId()+":"+orderAddDTO.getCommodityCode();
        Message message= MessageBuilder.withPayload(msgData)
                .setHeader("name","王翠花")
                .setHeader("orderId",1).build();
        rocketMQTemplate.sendMessageInTransaction("order-add-topic",message,orderAddDTO);
    }


    // 分页查询所有订单的业务逻辑层方法
    // pageNum是页码,pageSize是每页条数
    public JsonPage<Order> getAllOrdersByPage(Integer pageNum, Integer pageSize) {
        // PageHelper框架实现分页的核心操作:
        // 在要执行分页的查询运行之前,设置分页的条件
        // 设置的方式如下(固定的格式,PageHelper框架设计的)
        // PageHelper设置page为1就是查询第一页
        PageHelper.startPage(pageNum,pageSize);
        // 下面开始持久层方法的调用
        // 此方法运行时因为上面设置了分页条件,sql语句中会自动出现limit关键字
        List<Order> list=orderMapper.findAllOrders();
        // 查询结果list中包含的就是分页查询范围的数据了
        // 但是这个数据不包含分页信息(总页数,总条数,是否是首页,是否是末页等)
        // 我们要利用PageHelper框架提供的PageInfo类型,来进行返回
        // PageInfo对象可以既包含分页数据,又包含分页信息
        // 这些信息会在PageInfo对象实例化时自动计算,并赋值到PageInfo对象中
        return JsonPage.restPage(new PageInfo<>(list));
    }

}
